/*

Pop: this is the new shl util to generate html on the fly.

 */

(function(window, undefined){
    var shl = function(){
        return new shl.fn.init();
    }

    shl.basic = {
        /*
         * Basic functions
         * For parsing the raw instruction string array
         */
        _getUntil: function(option, charset){
            var res = [];
            while(option.ptr < option.str.length){
                if(this._charInCharset(option.str.charCodeAt(option.ptr), charset)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return res.join('');
        }
        ,
        _getExpect: function(option, charset){
            var res = [];
            while(option.ptr < option.str.length){
                if(this._charInCharset(option.str.charCodeAt(option.ptr), charset)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return false;
        }
        ,
        _getExpectChar: function(option, ch){
            var res = [];
            while(option.ptr < option.str.length){
                if(option.str.charCodeAt(option.ptr) == ch){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return false;
        }
        ,
        _getUntilChar: function(option, ch){
            var res = [];
            while(option.ptr < option.str.length){
                if(option.str.charCodeAt(option.ptr) == ch){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return res.join('');
        }
        ,
        _getUntilArray: function(option, charArray){
            var res = [];
            while(option.ptr < option.str.length){
                if(this._charInArray(option.str.charCodeAt(option.ptr), charArray)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return res.join('');
        }
        ,
        _getExpectArray: function(option, charArray){
            var res = [];
            while(option.ptr < option.str.length){
                if(this._charInArray(option.str.charCodeAt(option.ptr), charArray)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return false;
        }
        ,
        _getWhile: function(option, charset){
            var res = [];
            while(option.ptr < option.str.length){
                if(!this._charInCharset(option.str.charCodeAt(option.ptr), charset)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return res.join('');
        }
        ,
        _getWhileArray: function(option, charAry){
            var res = [];
            while(option.ptr < option.str.length){
                if(!this._charInArray(option.str.charCodeAt(option.ptr), charAry)){
                    return res.join('');
                }
                res[res.length] = option.str.charAt(option.ptr);
                option.ptr ++;
            }
            return res.join('');
        }
        ,
        _charInCharset: function(chCode, charset){
            var range = charset.range;
            for(var i in range){
                if(chCode >= range[i].from && chCode <= range[i].to){
                    return true;
                }
            }
            var equal = charset.equal;
            for(var i in equal){
                if(chCode == equal[i]){
                    return true;
                }
            }
            return false;
        }
        ,
        _charInArray: function(chCode, charArray){
            for(var i in charArray){
                if(chCode == charArray[i]){
                    return true;
                }
            }
            return false;
        }
        ,
        _getWord: function(option){
            return this._getWhile(option, shl.charset.setWord);
        }
        ,
        _skipAllSpace: function(option){
            this._getWhileArray(option, shl.charset.arySpaceChars);
        }
    }

    shl.parser = {

        /*
         * Step 1 functions for parsing the raw instructions into
         * instruction objects
         *
Data structure of different type of instruction objects

        tag:
        'word#word.word.word/' 'word#word.word.word>word|#word'
            type: 'tag'
            name:
            id:
            class: {}
            flags: [] of flag
        flag:
            name:
            id:
            class: {}
        close:
            type: 'close'
            flags: [] of flag
        attr:
        'word=`all char`' escape \` \\ 'word:all char,,' escape \\ \,
            type: 'attr'
            name:
            tmpl:
            trans:
        id:
            type: 'id'
            name:
        class:
            type: 'class'
            name:
        de-class:
            type: 'de-class'
            name:
        html:
            type: 'html'
            name:
        start:
            type: 'start'
            name:
        end:
            type: 'end'
            name:
        style:
            type: 'style'
            value:
        tmpl:
            type: 'tmpl'
            name:
        

        loop:
            type: 'loop'
            shl:
            data:
        cond:
            type: 'cond'
            shl:
            data:

         */
        _parseWordInstr: function(option){
            // possible pattern:
            // for(/word) /.word //.id
            // if(/word.word value) if(/word.word /word.word) //word => from the root
            // tag# tag. tag> tag/
            // attr:
            // using(/word.word)
            var tag = shl.basic._getWord(option);
            
        }
        ,
        /*
         * @param option
         *  ptr
         *  str
         *  shl
         */
        _parseShlCode: function(option){
            shl.basic._skipAllSpace(option);

            if(option.ptr == option.str.length){
                return {
                    type: 'eol'
                };
            } else {
                var chCode = option.str.charCodeAt(option.ptr);
                if(shl.basic._charInCharset(chCode, shl.charset.setWord)){
                    // possible pattern:
                    // for(/word) /.word //.id
                    // if(/word.word value) if(/word.word /word.word) //word => from the root
                    // tag# tag. tag> tag/
                    // attr:
                    // using(/word.word)
                    return shl.parser._parseWordInstr(option);
                } else if(chCode == 58 ){ // :
                // html

                } else if(chCode == 60){ // <
                // close tag
                    
                } else if(chCode == 36){ // $
                // block possible pattern : $s:... $e:...

                } else if(chCode == 64){ // @
                // cascading style sheet

                } else if(chCode == 35){ // #
                // id

                } else if(chCode == 46){ // .
                // class

                } else if(chCode == 126){ // ~
                // de class

                } else if(chCode == 47){ // /
                // template

                } else if(chCode == 38){ // &
                // quick html

                }
                var d ={

                }
                return option;
            }


        }

    }

    shl.fn = shl.prototype = {
        
        init: function(){

        }
        ,
        var1: null
    }

    shl.fn.init.prototype = shl.fn;
    window.shl = shl;

    shl.charset = {
        setWord:{
            range:[
            {
                from:65,
                to:90
            },
            {
                from:97,
                to:122
            },
            {
                from:48,
                to:57
            }
            ],
            equal:[
            45,
            95
            ]
        },
        arySingleQuoteAndBackSlash: [
        92, 39
        ],
        backSlash: 92,
        singleQuote: 39,
        doubleQuote: 34,
        backQuote: 96,
        column: 58,
        lessThan: 60,
        dollar: 36,
        at: 64,
        harsh: 35,
        dot: 46,
        tilde:126,
        slash: 47,
        amp: 38,
        backSlash:92,
        arySpaceChars : [
        32, 9
        ]
    }
})(window)



$().ready(function(){
    initPage();
})

function initPage(){
    debugFuncs();

    basicTestSet();
}

function debugFuncs(){
    debug(shl.parser._parseShlCode({
        str: ' \t   word   ',
        ptr: 4,
        shl: {}
    }))
}

function basicTestSet(){
    describe('get until char()', {
        untilBackQuote: function(){
            var s = {
                ptr: 0,
                str: 'word `is in here'
            };
            var w = shl.basic._getUntilChar(s, shl.charset.backQuote);

            value_of('`'.charCodeAt(0)).should_be(shl.charset.backQuote);
            value_of('\''.charCodeAt(0)).should_be(shl.charset.singleQuote);
            value_of('"'.charCodeAt(0)).should_be(shl.charset.doubleQuote);
            value_of(w).should_be('word ');
            value_of(s.ptr).should_be(5);
        },
        'until single quote': function(){
            var s = {
                ptr: 0,
                str: "bal bla `` \" '"
            };
            var w = shl.basic._getUntilChar(s, shl.charset.singleQuote);
            value_of(w).should_be('bal bla `` " ');
            value_of(s.ptr).should_be(13);
        }
    });

    describe('get expect char()', {
        'while word': function(){
            var s = {
                str:'this123409823_-12ji,fwe',
                ptr:2
            };
            var w = shl.basic._getWhile(s, shl.charset.setWord);

            value_of(w).should_be('is123409823_-12ji');
        }
        ,
        'while word 2': function(){
            var s = {
                str:'ui-icon ui-some',
                ptr:0
            };
            var w = shl.basic._getWhile(s, shl.charset.setWord);

            value_of(w).should_be('ui-icon');
        }
        ,
        'get word table>': function(){
            var s = {
                str:'table>',
                ptr: 0
            }
            var w = shl.basic._getWord(s);

            value_of(w).should_be('table');
            value_of(s.ptr).should_be(5);
        }
    });

    describe('skip spaces',{
        'skip until to word 1': function(){
            var s = {
                str: '   \t td/',
                ptr:1
            }
            var w = shl.basic._skipAllSpace(s);
            value_of(s.ptr).should_be(5);
        }
    })
}